﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Game.ui;
using GameFramework.common;
using GameFramework.timer;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;

namespace GameFramework.UI
{
    //TODO
    //方案1：每个场景一个节点，挂在一个UIDocument，这个document对应多个UXML,切换场景时激活和失活对应的场景UIDocument节点
    //UI分类：场景UI，TipsUI,占位UI(游戏启动时场景UI和TipsUI未加载完成时显示的UI，加载完成后会隐藏占位UI)
    public class UIManager:MonoSingleton<UIManager>
    {
        //view类型根据所属的场景视图管理器名字分组
        public static Dictionary<string,List<Type>> baseViewTypeGroupBySceneName = new Dictionary<string, List<Type>>();//每个场景的UI类型
        public static Dictionary<Type,string> baseview2SceneName = new Dictionary<Type,string>();//每个场景的UI类型
        private SceneViewManager[] sceneViewManagers;//所有的场景UI管理器
        [SerializeField]
        public string defaultSceneView;//默认显示的场景UI管理器名字
        [SerializeField]
        public GameObject placeHolderUI;//启动时的占位UI
        public UIDocument tipsDocument;//tipsUI容器
        //TODO tips管理器
        
        private SceneViewManager currentSceneViewManager;//当前场景UI管理器
        
        
        
        
        private void Start()
        {
            NullRefChecker.Validate(this);
            tipsDocument.rootVisualElement.pickingMode = PickingMode.Ignore;
            preLoadViews();
            
            // switchSceneView(defaultSceneView);
            //等所有的场景UI管理器脚本的Start方法执行完再显示界面
            StartCoroutine(afterViewLoaded());
            //TODO 加载后的操作应该发布事件，不应该直接调用

        }

        private IEnumerator afterViewLoaded()
        {
            yield return null;
            show<GameInitingView>(false);
            
            closePlaceHolderUI();
        }

        private void preLoadViews()
        {
            cacheAllViews();
            Transform sceneUiParent = transform.Find("SceneUI");
            sceneViewManagers = sceneUiParent.GetComponentsInChildren<SceneViewManager>();

            foreach (SceneViewManager manager in sceneViewManagers)
            {
                manager.preLoadViews();
                // manager.gameObject.SetActive(false);
                manager.hideAllViewImmediately();
            }
        }

        private void cacheAllViews()
        {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            Type[] types = executingAssembly.GetTypes();
            foreach (Type t in types)
            {
                if (!typeof(BaseView).IsAssignableFrom(t))
                {
                    continue;
                }

                ViewAttribute attribute = t.GetCustomAttribute<ViewAttribute>();
                if (attribute == null)
                {
                    continue;
                }

                string viewManagerName = attribute.SceneViewManagerName;
                if (viewManagerName == null || viewManagerName.Length == 0)
                {
                    continue;
                }
                
                if (!baseViewTypeGroupBySceneName.ContainsKey(viewManagerName))
                {
                    baseViewTypeGroupBySceneName.Add(viewManagerName,new List<Type>());
                }

                List<Type> list = baseViewTypeGroupBySceneName[viewManagerName];
                baseview2SceneName.Add(t,viewManagerName);
                list.Add(t);
            }

        }

        private void closePlaceHolderUI()
        {
            if (placeHolderUI != null)
            {
                placeHolderUI.gameObject.SetActive(false);
            }
        }

        #region 场景UI切换

        //直接切换到其他场景的UI，如果之前有打开的界面，则显示之前的界面
        public void switchSceneView(string viewName)
        {
            if (currentSceneViewManager!=null && currentSceneViewManager.managerName.Equals(viewName))
            {
                return;
            }
            
            foreach (SceneViewManager manager in sceneViewManagers)
            {
                if (manager.managerName.Equals(viewName))
                {
                    if (currentSceneViewManager != null)
                    {
                        currentSceneViewManager.hideAllViewImmediately();
                    }
                    
                    currentSceneViewManager = manager;
                    currentSceneViewManager.recoverViewStack();
                }
            }
        }

        #endregion


        #region 显示隐藏当前场景下的view

        //显示场景UI，如果当前的场景UI管理器不存在或要显示的UI不是当前场景的，则先切换场景
        //如果是先切换场景，再显示UI，有2种情况：
        //1.待显示的UI和场景最后显示的UI一致，则直接恢复视图栈即可
        //2.待显示UI不是最后显示的UI，且在视图栈中，则移除栈顶视图直到和待显示UI一致，然后恢复视图栈
        //3.待显示的UI不是在视图栈中，则直接显示
        public void show<T>(bool add2Stack = true)   
        {
            //TODO 自动根据view所属的场景来切换场景UI管理器
            if (!baseview2SceneName.ContainsKey(typeof(T)))
            {
                //要显示的UI不属于任何场景
                Debug.LogError("显示的UI不存在："+typeof(T).Name);
                return;
            }

            string sceneName = baseview2SceneName[typeof(T)];
            if (currentSceneViewManager == null || !currentSceneViewManager.managerName.Equals(sceneName))
            {
                switchSceneView(sceneName);
            }

            currentSceneViewManager.show<T>(add2Stack);
        }

        //回退到上一个界面
        public void back()
        {
            if (currentSceneViewManager == null)
            {
                return;
            }
            currentSceneViewManager.back();
        }
        /**
         * 关闭最上层界面
         */
        public void hide<T>()
        {
            currentSceneViewManager.hide<T>();
        }

        #endregion



        







        
    }
    
    
}